# -*- coding: utf-8 -*-

from core.viewset import CustomModelViewSet
from core.response import JsonResponse
from rest_framework.decorators import action
from .models import Bug, BugOperate, BugComment
from .serializers import (
    BugSerializer,
    BugOperateSerializer,
    BugCommentSerializer,
    BugOperateCreateAndUpdateSerializer,
)
from .resources import BugResources
from .filters import (
    BugFilterSet,
    BugOperateFilterSet,
    BugCommentFilterSet,
)
from docx import Document
from bs4 import BeautifulSoup
from django.http import FileResponse
import io
from pathlib import Path
from application.settings import BASE_DIR, MEDIA_URL
from docx.shared import Inches


def remove_base_url(url):
    # 查找 '/media/' 的位置
    pos = url.find(MEDIA_URL)
    if pos != -1:
        # 返回 '/media/' 及其后面的部分
        return url[pos:]
    return url  # 如果没有找到 '/media/', 返回原始 URL


class BugViewSet(CustomModelViewSet):
    """
    缺陷管理接口
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """

    queryset = Bug.objects.all()
    serializer_class = BugSerializer
    filterset_class = BugFilterSet
    import_resources = BugResources
    export_resources = BugResources

    @action(detail=False, methods=["POST"])
    def export_to_word(self, request, *args, **kwargs):
        bugs = Bug.objects.filter(id__in=request.data["ids"].split(","))
        doc = Document()

        # 添加标题
        doc.add_heading("缺陷报表", 0)

        # 获取Word文档可用的最大宽度（通常为6-7英寸）
        max_width = Inches(6)

        index = 0

        for bug in bugs:
            index += 1
            doc.add_paragraph(
                f"缺陷 {index}：【{bug.number}】{bug.name}", style="Heading 1"
            )
            soup = BeautifulSoup(bug.description, "html.parser")

            for p in soup.find_all("p"):
                if p.img:  # 如果p标签内含有图片
                    image_url = remove_base_url(p.img["src"])
                    image_path = BASE_DIR.joinpath(Path(image_url).relative_to("/"))

                    # 确保使用正确格式的路径字符串与图片尺寸
                    doc.add_picture(str(image_path), width=max_width)
                else:
                    # 添加文本到Word文档
                    doc.add_paragraph(p.text)

        # 使用BytesIO处理文件流
        file_stream = io.BytesIO()
        doc.save(file_stream)
        file_stream.seek(0)  # 重置流位置

        # 创建响应并发送文件
        response = FileResponse(
            file_stream, as_attachment=True, filename="缺陷报表.docx"
        )
        return response

    @action(detail=True, methods=["PUT"])
    def associate_bugs(self, request, *args, **kwargs):
        try:
            target_bug = self.get_object()
            associates = request.data.get("associates", [])
            bugs_to_associate = Bug.objects.filter(number__in=associates)

            # 如果没有找到对应的Bug，返回错误
            if len(bugs_to_associate) != len(associates):
                missing_associates = set(associates) - set(
                    [bug.number for bug in bugs_to_associate]
                )
                return JsonResponse(
                    code=500, msg=f"未找到以下缺陷：{missing_associates}"
                )

            target_bug.related_bugs.add(*bugs_to_associate)
            return JsonResponse(msg="关联成功")
        except Exception as ex:
            return JsonResponse(code=500, msg=f"关联失败：{ex}")


class BugOperateViewSet(CustomModelViewSet):
    """
    缺陷操作管理接口
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """

    queryset = BugOperate.objects.all()
    serializer_class = BugOperateSerializer
    create_serializer_class = BugOperateCreateAndUpdateSerializer
    update_serializer_class = BugOperateCreateAndUpdateSerializer
    filterset_class = BugOperateFilterSet


class BugCommentViewSet(CustomModelViewSet):
    """
    缺陷评论管理接口
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """

    queryset = BugComment.objects.all()
    serializer_class = BugCommentSerializer
    filterset_class = BugCommentFilterSet
